﻿using static Bentley.CIMNET.CIMGeometry.Solid.SolidUtil.Modify;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Bentley.CifNET.LinearGeometry;
using System.Net;
using Bentley.CIMNET.CIMGeometry.Mesh;
using CheccCoverplateCulvertAssemble.Common.Total;
using CheccCoverplateCulvertAssemble.Tools;

namespace BoxCulvert.service.cave
{
    public class CreateSideDitchFallWell
    {
        #region Fileds

        // 井底厚度	
        private double _sideDitchFallWell_ShaftBottomThickness;
        // 沉砂池深	
        private double _sideDitchFallWell_GritBasinDeep;
        // 井底中心长	
        private double _sideDitchFallWell_ShaftBottomCenterLength;
        // 井深		
        private double _sideDitchFallWell_ShaftDeep;
        // 井壁顶宽	
        private double _sideDitchFallWell_ShaftWallTopWidth;
        // 井壁坡比1: n
        private double _sideDitchFallWell_ShaftWallSlopeRatio;
        // 井外平台宽	
        private double _sideDitchFallWell_ShaftOuterWidth;
        // 井外开挖坡度
        private double _sideDitchFallWell_ShaftOuterSlope;
        // 边沟外壁偏距
        private double _sideDitchFallWell_SideDitchOutWallSetover;
        // 边沟深度	
        private double _sideDitchFallWell_SideDitchDeep;
        // 边沟内坡比	
        private double _sideDitchFallWell_SideDitchInSlopeRatio;
        // 边沟底宽	
        private double _sideDitchFallWell_SideDitchBottomWidth;
        // 边沟外坡比	
        private double _sideDitchFallWell_SideDitchOutSlopeRatio;
        // 外壁护面高	
        private double _sideDitchFallWell_OutWallMaskHeight;
        // 护面坡比1: n
        private double _sideDitchFallWell_MaskSlopeRatio;
        // 左端开口长	
        private double _sideDitchFallWell_FirstMemberStartTalkLength;
        // 右端开口长	
        private double _sideDitchFallWell_RightMemberStartTalkLength;
        // 边沟绘制长
        private double _sideDitchFallWell_SideDitchDrawLength;
        // 井底纵坡	
        private double _sideDitchFallWell_ShaftBottomEndlongSlope;
        // 是否选用自动计算的井深
        private bool _sideDitchFallWell_CheckAuto;

        private string _clearSpan = null;
        private string _clearHeight = null;

        #endregion


        public CreateSideDitchFallWell(SideDitchFallWell sideDitchFallWell, string spanAndHeadroom)
        {
            this._sideDitchFallWell_ShaftBottomThickness = sideDitchFallWell.SideDitchFallWell_ShaftBottomThickness / 100;
            this._sideDitchFallWell_GritBasinDeep = sideDitchFallWell.SideDitchFallWell_GritBasinDeep / 100;
            this._sideDitchFallWell_ShaftBottomCenterLength = sideDitchFallWell.SideDitchFallWell_ShaftBottomCenterLength / 100;
            this._sideDitchFallWell_ShaftDeep = sideDitchFallWell.SideDitchFallWell_ShaftDeep / 100;
            this._sideDitchFallWell_ShaftWallTopWidth = sideDitchFallWell.SideDitchFallWell_ShaftWallTopWidth / 100;
            this._sideDitchFallWell_ShaftWallSlopeRatio = sideDitchFallWell.SideDitchFallWell_ShaftWallSlopeRatio;
            this._sideDitchFallWell_ShaftOuterWidth = sideDitchFallWell.SideDitchFallWell_ShaftOuterWidth / 100;
            this._sideDitchFallWell_ShaftOuterSlope = sideDitchFallWell.SideDitchFallWell_ShaftOuterSlope;
            this._sideDitchFallWell_SideDitchOutWallSetover = sideDitchFallWell.SideDitchFallWell_SideDitchOutWallSetover / 100;
            this._sideDitchFallWell_SideDitchDeep = sideDitchFallWell.SideDitchFallWell_SideDitchDeep / 100;
            this._sideDitchFallWell_SideDitchInSlopeRatio = sideDitchFallWell.SideDitchFallWell_SideDitchInSlopeRatio;
            this._sideDitchFallWell_SideDitchBottomWidth = sideDitchFallWell.SideDitchFallWell_SideDitchBottomWidth / 100;
            this._sideDitchFallWell_SideDitchOutSlopeRatio = sideDitchFallWell.SideDitchFallWell_SideDitchOutSlopeRatio;
            this._sideDitchFallWell_OutWallMaskHeight = sideDitchFallWell.SideDitchFallWell_OutWallMaskHeight / 100;
            this._sideDitchFallWell_MaskSlopeRatio = sideDitchFallWell.SideDitchFallWell_MaskSlopeRatio;
            this._sideDitchFallWell_FirstMemberStartTalkLength = sideDitchFallWell.SideDitchFallWell_FirstMemberStartTalkLength / 100;
            this._sideDitchFallWell_RightMemberStartTalkLength = sideDitchFallWell.SideDitchFallWell_RightMemberStartTalkLength / 100;
            this._sideDitchFallWell_SideDitchDrawLength = sideDitchFallWell.SideDitchFallWell_SideDitchDrawLength / 100;
            this._sideDitchFallWell_ShaftBottomEndlongSlope = sideDitchFallWell.SideDitchFallWell_ShaftBottomEndlongSlope / 100;
            this._sideDitchFallWell_CheckAuto = sideDitchFallWell.SideDitchFallWell_CheckAuto;

            this._clearSpan = spanAndHeadroom.Split('×')[0];
            this._clearHeight = spanAndHeadroom.Split('×')[1];

        }

        public List<Element> CreateSideDitchFallWellBody(double Degrees)
        {
            double span = Convert.ToDouble(_clearSpan);
            List<Element> entity = new List<Element>();


            #region 绘制井底

            double topleftDegrees = 90 - (Degrees);
            Angle ang = Angle.FromDegrees(topleftDegrees);
            DVector3d resultDvec = DVector3d.UnitX.RotateXY(Angle.FromDegrees(Degrees));
            double addLength = Math.Abs(ang.Tan * span);
            double downHeight = addLength * 1.5 * this._sideDitchFallWell_ShaftBottomEndlongSlope;

            // 井底左侧点 有坡度剪不到墙 向左侧推一个延申长度
            DPoint3d[] points_ShaftBottom =
            {
                new DPoint3d(-addLength, span / 2, 0)*Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster,
                new DPoint3d(-addLength, span / 2, this._sideDitchFallWell_ShaftBottomThickness /*- addLength * this._sideDitchFallWell_ShaftBottomEndlongSlope*/)*Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster,
                new DPoint3d(-addLength, -span / 2, this._sideDitchFallWell_ShaftBottomThickness/*- addLength * this._sideDitchFallWell_ShaftBottomEndlongSlope*/)*Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster,
                new DPoint3d(-addLength, -span / 2, 0)*Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster,
                new DPoint3d(-addLength, span / 2, 0)*Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster
            };

            // 延x方向构造坡度的线 两侧有坡比 所以构造时 将左侧长度延申一个加长的length
            LineElement templineElement = GetSlopLinee(this._sideDitchFallWell_ShaftBottomCenterLength + addLength * 2 + this._sideDitchFallWell_ShaftWallTopWidth, this._sideDitchFallWell_ShaftBottomEndlongSlope);
            ShapeElement sectiongElement = new(GeneralBank.Default3DModel, null, points_ShaftBottom);

            BCIMNETGS.SolidUtil.Create.BodyFromSweep(out SolidKernelEntity soild, sectiongElement.GetCurveVector(), templineElement.GetCurveVector(), GeneralBank.Default3DModel, true, true, false, null, null, null, null);

            // 两侧涵洞是斜涵 分别需要向左向下移动
            DPoint3d movePoint3d = new DPoint3d(-addLength / 2, 0, -downHeight) * GeneralBank.UorToMeters;
            DTransform3d transform3D = DTransform3d.Identity;
            transform3D.Translation = movePoint3d;
            TransformBody(ref soild, transform3D);

            #endregion


            #region Get well bottom points of top

            /*
             俯视图 第一个点在左下角 逆时针依次为 第二个 第三个
             */

            DPoint3d staP_Bottom = new DPoint3d();
            DPoint3d secondP_Bottom = new DPoint3d();
            DPoint3d thirdP_Bottom = new DPoint3d();
            DPoint3d endP_Bottom = new DPoint3d();

            SubEntity[] subEntities2;
            Bentley.DgnPlatformNET.SolidUtil.GetBodyVertices(out subEntities2, soild);

            SolidUtil.EvaluateVertex(out staP_Bottom, subEntities2[5]);
            SolidUtil.EvaluateVertex(out secondP_Bottom, subEntities2[1]);
            SolidUtil.EvaluateVertex(out thirdP_Bottom, subEntities2[2]);
            SolidUtil.EvaluateVertex(out endP_Bottom, subEntities2[6]);

            double addZ = _sideDitchFallWell_ShaftDeep * GeneralBank.UorToMeters - secondP_Bottom.Z;
            //double addZ = _sideDitchFallWell_ShaftDeep - _sideDitchFallWell_ShaftBottomThickness;
            //addZ *= Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;
            double addX = addZ * _sideDitchFallWell_ShaftWallSlopeRatio;

            //SolidUtil.EvaluateVertex(out DPoint3d staP, subEntities2[6]);
            //SolidUtil.EvaluateVertex(out DPoint3d endP, subEntities2[7]);
            //DSegment3d dSegment3D = new DSegment3d(staP, endP);
            //new LineElement(GeneralBank.Default3DModel, null, dSegment3D).AddToModel(); return;

            #endregion


            #region Outer

            double outerZ = _sideDitchFallWell_ShaftDeep * GeneralBank.UorToMeters;
            DPoint3d staP_Top = new DPoint3d(staP_Bottom.X, staP_Bottom.Y - addX, outerZ);
            DPoint3d secondP_Top = new DPoint3d(secondP_Bottom.X + addX, secondP_Bottom.Y - addX, outerZ);
            DPoint3d thirdP_Top = new DPoint3d(thirdP_Bottom.X + addX, thirdP_Bottom.Y + addX, outerZ);
            DPoint3d endP_Top = new DPoint3d(endP_Bottom.X, endP_Bottom.Y + addX, outerZ);

            DPoint3d[] points_OutBottom = { staP_Bottom, secondP_Bottom, thirdP_Bottom, endP_Bottom };
            DPoint3d[] points_OutTop = { staP_Top, secondP_Top, thirdP_Top, endP_Top };

            ShapeElement shapeBottom = new ShapeElement(GeneralBank.Default3DModel, null, points_OutBottom); //shapeBottom.AddToModel();
            ShapeElement shapeTop = new ShapeElement(GeneralBank.Default3DModel, null, points_OutTop); //shapeTop.AddToModel();

            var internalSections = new List<CurveVector>
            {
                shapeBottom.GetCurveVector(),
                shapeTop.GetCurveVector()
            };
            Create.BodyFromLoft(out SolidKernelEntity outerSolid, internalSections.ToArray(), internalSections.Count, internalSections.ToArray(), 0, GeneralBank.Default3DModel, false, false);

            //if (outerSolid != null)
            //{
            //    var ele_soild = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, outerSolid, null);
            //    //ele_soild.AddToModel(); return;
            //}

            #endregion


            #region Inner

            double topWidth = this._sideDitchFallWell_ShaftWallTopWidth * Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;

            DPoint3d staP_TopIn = new DPoint3d(staP_Top.X, staP_Top.Y + topWidth, staP_Top.Z);
            DPoint3d secondP_TopIn = new DPoint3d(secondP_Top.X - topWidth, secondP_Top.Y + topWidth, secondP_Top.Z);
            DPoint3d thirdP_TopIn = new DPoint3d(thirdP_Top.X - topWidth, thirdP_Top.Y - topWidth, thirdP_Top.Z);
            DPoint3d endP_TopIn = new DPoint3d(endP_Top.X, endP_Top.Y - topWidth, endP_Top.Z);

            double offserOfZ = topWidth * this._sideDitchFallWell_ShaftBottomEndlongSlope;
            DPoint3d staP_BottomIn = new DPoint3d(staP_Bottom.X, staP_Bottom.Y + topWidth, staP_Bottom.Z);
            DPoint3d secondP_BottomIn = new DPoint3d(secondP_Bottom.X - topWidth, secondP_Bottom.Y + topWidth, secondP_Bottom.Z - offserOfZ);
            DPoint3d thirdP_BottomIn = new DPoint3d(thirdP_Bottom.X - topWidth, thirdP_Bottom.Y - topWidth, secondP_Bottom.Z - offserOfZ);
            DPoint3d endP_BottomIn = new DPoint3d(endP_Bottom.X, endP_Bottom.Y - topWidth, endP_Bottom.Z);

            DPoint3d[] points_InBottom = { staP_BottomIn, secondP_BottomIn, thirdP_BottomIn, endP_BottomIn };
            DPoint3d[] points_InTop = { staP_TopIn, secondP_TopIn, thirdP_TopIn, endP_TopIn };

            ShapeElement shapeBottomIn = new ShapeElement(GeneralBank.Default3DModel, null, points_InBottom); //shapeBottomIn.AddToModel();
            ShapeElement shapeTopIn = new ShapeElement(GeneralBank.Default3DModel, null, points_InTop); //shapeTopIn.AddToModel();

            var internalSectionsIn = new List<CurveVector>
            {
                shapeBottomIn.GetCurveVector(),
                shapeTopIn.GetCurveVector()
            };
            Create.BodyFromLoft(out SolidKernelEntity innerSolid, internalSectionsIn.ToArray(), internalSectionsIn.Count, internalSectionsIn.ToArray(), 0, GeneralBank.Default3DModel, false, false);

            //if (innerSolid != null)
            //{
            //    var ele_soild = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, innerSolid, null);
            //    ele_soild.AddToModel(); return;
            //}

            #endregion


            #region 边沟

            double length = staP_Top.Distance(endP_Top) / 2;
            DPoint3d lineStaP = DPoint3d.Zero - resultDvec * (length / ang.Cos);
            lineStaP.Z = (_sideDitchFallWell_ShaftDeep) * GeneralBank.UorToMeters;
            DPoint3d lineEndP = DPoint3d.Zero + resultDvec * (length / ang.Cos);
            lineEndP.Z = lineStaP.Z;
            //LineElement line = new LineElement(GeneralBank.Default3DModel, null, new DSegment3d(lineStaP, lineEndP));
            //line.AddToModel();

            #region first border points

            double leftX = _sideDitchFallWell_SideDitchInSlopeRatio * _sideDitchFallWell_SideDitchDeep * GeneralBank.UorToMeters;
            double rightX = _sideDitchFallWell_SideDitchDeep * GeneralBank.UorToMeters * _sideDitchFallWell_SideDitchOutSlopeRatio;

            DPoint3d forwardP1 = lineStaP;
            DPoint3d forwardP5 = new DPoint3d(secondP_TopIn.X, secondP_TopIn.Y - topWidth, secondP_TopIn.Z);

            DPoint3d forwardP2 = new DPoint3d(lineStaP.X + leftX, forwardP1.Y, lineStaP.Z - _sideDitchFallWell_SideDitchDeep * GeneralBank.UorToMeters);

            DPoint3d forwardP4 = new DPoint3d(forwardP5.X, forwardP5.Y, forwardP5.Z);
            DPoint3d forwardP3 = new DPoint3d(forwardP4.X - rightX, forwardP4.Y, lineStaP.Z - _sideDitchFallWell_SideDitchDeep * GeneralBank.UorToMeters);

            #endregion

            #region second border points

            DPoint3d backP1 = lineEndP;
            DPoint3d backP5 = new DPoint3d(thirdP_TopIn.X, thirdP_TopIn.Y + topWidth, thirdP_TopIn.Z);

            DPoint3d backP2 = new DPoint3d(lineEndP.X + leftX, backP1.Y, lineEndP.Z - _sideDitchFallWell_SideDitchDeep * GeneralBank.UorToMeters);

            DPoint3d backP4 = new DPoint3d(backP5.X, backP5.Y, backP5.Z);
            DPoint3d backP3 = new DPoint3d(backP4.X - rightX, backP4.Y, lineEndP.Z - _sideDitchFallWell_SideDitchDeep * GeneralBank.UorToMeters);

            #endregion

            #region MyRegion

            PolyfaceHeader polyface = CreatePolyfaceHeader(new List<DPoint3d> { secondP_Bottom, staP_Bottom, staP_Top, secondP_Top }, new List<DPoint3d>()); 
            CurveVector drapedCurve = polyface.DrapeLinestring(new DPoint3d[] { forwardP3, forwardP2 }, DVector3d.UnitY);
            drapedCurve.GetStartEnd(out forwardP2, out forwardP3);

            PolyfaceHeader polyface2 = CreatePolyfaceHeader(new List<DPoint3d> { thirdP_Bottom, endP_Bottom, endP_Top, thirdP_Top }, new List<DPoint3d>());
            CurveVector drapedCurve2 = polyface2.DrapeLinestring(new DPoint3d[] { backP3, backP2 }, DVector3d.UnitY);
            drapedCurve2.GetStartEnd(out backP2, out backP3);

            DPoint3d originforwardP3 = new DPoint3d(forwardP3.X, forwardP3.Y, forwardP3.Z);
            DPoint3d originforwardP2 = new DPoint3d(forwardP2.X, forwardP2.Y, forwardP2.Z);

            DPoint3d originBackP3 = new DPoint3d(backP3.X, backP3.Y, backP3.Z);
            DPoint3d originBackP2 = new DPoint3d(backP2.X, backP2.Y, backP2.Z);

            Line line = Line.Create1(backP2, forwardP2);
            forwardP2 = Line.Create2(line.StartPoint.Coordinates, line.Direction, line.Length + topWidth).EndPoint.Coordinates;
            forwardP3.Y = forwardP2.Y;
            backP2 = Line.Create3(line.EndPoint.Coordinates, line.Direction, line.Length + topWidth).StartPoint.Coordinates;
            backP3.Y = backP2.Y;

            #endregion

            #region create shape

            DPoint3d[] points_Forward = { forwardP1, forwardP2, forwardP3, forwardP4, forwardP1 };
            ShapeElement shapForward = new(GeneralBank.Default3DModel, null, points_Forward); // shapForward.AddToModel();

            DPoint3d[] points_Back = { backP1, backP2, backP3, backP4, backP1 };
            ShapeElement shapBack = new(GeneralBank.Default3DModel, null, points_Back); // shapBack.AddToModel(); // return;

            #endregion

            #region 拉伸成体

            var curves = new List<CurveVector>
            {
                shapForward.GetCurveVector(),
                shapBack.GetCurveVector()
            };
            Create.BodyFromLoft(out SolidKernelEntity sideSoli, curves.ToArray(), curves.Count, curves.ToArray(), 0, GeneralBank.Default3DModel, false, false);

            //if (sideSoli != null)
            //{
            //    var ele_soild = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, sideSoli, null);
            //    //ele_soild.AddToModel(); /*return;*/
            //}

            #endregion

            #endregion


            #region 左右开口端加长

            forwardP2 = originforwardP2;
            forwardP3 = originforwardP3;
            backP2 = originBackP2;
            backP3 = originBackP3;

            double leftLength = _sideDitchFallWell_FirstMemberStartTalkLength * GeneralBank.UorToMeters;
            double rightLength = _sideDitchFallWell_RightMemberStartTalkLength * GeneralBank.UorToMeters;


            DPoint3d backP11 = new DPoint3d(backP1.X, backP1.Y + leftLength, backP1.Z);
            DPoint3d backP22 = new DPoint3d(backP2.X, backP2.Y + leftLength, backP2.Z);
            DPoint3d backP44 = new DPoint3d(backP4.X, backP4.Y + leftLength, backP4.Z);
            DPoint3d backP33 = new DPoint3d(backP3.X, backP3.Y + leftLength, backP3.Z);

            DPoint3d forwardP11 = new DPoint3d(forwardP1.X, forwardP1.Y - rightLength, forwardP1.Z);
            DPoint3d forwardP22 = new DPoint3d(forwardP2.X, forwardP2.Y - rightLength, forwardP2.Z);
            DPoint3d forwardP44 = new DPoint3d(forwardP4.X, forwardP4.Y - rightLength, forwardP4.Z);
            DPoint3d forwardP33 = new DPoint3d(forwardP3.X, forwardP3.Y - rightLength, forwardP3.Z);

            DPoint3d[] leftEntrance = { backP1, backP2, backP3, backP4, backP44, backP33, backP22, backP11 };
            DPoint3d[] rightEntrance = { forwardP1, forwardP2, forwardP3, forwardP4, forwardP44, forwardP33, forwardP22, forwardP11 };

            if (leftLength > 0)
            {
                ShapeElement shap_LeftEntrance = new(GeneralBank.Default3DModel, null, leftEntrance);
                //shap_LeftEntrance.AddToModel();
                entity.Add(shap_LeftEntrance);
            }

            if (rightLength > 0)
            {
                ShapeElement shap_RightEntrance = new(GeneralBank.Default3DModel, null, rightEntrance);
                //shap_RightEntrance.AddToModel();
                entity.Add(shap_RightEntrance);
            }

            #endregion


            #region Outer - Inner - said

            SolidKernelEntity[] tools = { sideSoli, innerSolid };
            BentleyStatus status = Modify.BooleanSubtract(ref outerSolid, ref tools, tools.Length);

            //SolidKernelEntity[] tools2 = { innerSolid };
            //BentleyStatus status2 = Modify.BooleanSubtract(ref outerSolid, ref tools2, tools2.Length);

            //if (status == BentleyStatus.Success)
            //{
            //    var ele_soild = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, outerSolid, null);
            //    ele_soild.AddToModel(); return;
            //}

            #endregion


            #region cut 

            // 构造剪切线
            LineElement lineElement1 = new LineElement(GeneralBank.Default3DModel, null, new DSegment3d(DPoint3d.Zero - resultDvec * span * 10 * GeneralBank.UorToMeters, DPoint3d.Zero + resultDvec * span * 10 * GeneralBank.UorToMeters));
            //lineElement1.AddToModel();


            // 用线剪切井底
            BCIMNETGS.SolidUtil.Modify.CutSolidsWithCurves(out SolidKernelEntity[] solidKernels, soild, lineElement1.GetCurveVector(), SolidCutMethod.Split, SolidCutDirection.Both, SolidCutMode.Through, 0);
            if (solidKernels != null) soild = solidKernels[0];
            if (soild is not null)
            {
                var ele = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, soild, null);
                entity.Add(ele);

            }

            // 用线剪切墙
            BCIMNETGS.SolidUtil.Modify.CutSolidsWithCurves(out SolidKernelEntity[] solidKernels2, outerSolid, lineElement1.GetCurveVector(), SolidCutMethod.Split, SolidCutDirection.Both, SolidCutMode.Through, 0);
            if (solidKernels2 != null) outerSolid = solidKernels2[0];
            if (outerSolid is not null)
            {
                var ele_soild = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, outerSolid, null);
                entity.Add(ele_soild);
            }

            #endregion


            #region 外壁湖面

            DPoint3d staP_ProtectWall = new DPoint3d(secondP_Top.X - topWidth, secondP_Top.Y, secondP_Top.Z);
            DPoint3d secondP_ProtectWall = secondP_Top;
            DPoint3d thirdP_ProtectWall = thirdP_Top;
            DPoint3d endP_ProtectWall = new DPoint3d(thirdP_Top.X - topWidth, thirdP_Top.Y, thirdP_Top.Z);
            DPoint3d[] points_ProtectWall = { staP_ProtectWall, secondP_ProtectWall, thirdP_ProtectWall, endP_ProtectWall };

            ShapeElement shapeProtectWall = new ShapeElement(GeneralBank.Default3DModel, null, points_ProtectWall); // shapeProtectWall.AddToModel();
            LineElement lineElement_ProtectWall = GetSlopLinee(secondP_ProtectWall, this._sideDitchFallWell_OutWallMaskHeight, this._sideDitchFallWell_ShaftOuterSlope); // lineElement_ProtectWall.AddToModel();
            BCIMNETGS.SolidUtil.Create.BodyFromSweep(out SolidKernelEntity soild_ProtectWall, shapeProtectWall.GetCurveVector(), lineElement_ProtectWall.GetCurveVector(), GeneralBank.Default3DModel, true, true, false, null, null, null, null);

            if (soild_ProtectWall is not null)
            {
                var ele = DraftingElementSchema.ToElement(GeneralBank.Default3DModel, soild_ProtectWall, null);
                entity.Add(ele);
            }

            #endregion


            #region 外壁护面

            SubEntity[] subEntities;
            Bentley.DgnPlatformNET.SolidUtil.GetBodyVertices(out subEntities, soild_ProtectWall);

            SolidUtil.EvaluateVertex(out DPoint3d pointsFirst, subEntities[1]); // Y轴正方向上的点
            SolidUtil.EvaluateVertex(out DPoint3d pointsSecond, subEntities[2]); // Y轴负方向上的点

            double offsetX = Math.Abs(pointsFirst.X - pointsSecond.X);
            double addX_ShaftOuterWidth = _sideDitchFallWell_ShaftOuterWidth * GeneralBank.UorToMeters;
            DPoint3d pointsThird = new DPoint3d(pointsSecond.X + addX_ShaftOuterWidth, pointsSecond.Y, pointsSecond.Z);
            // 第三个点需要找到边坡线交点
            // 第五个点和第六个点 = 第三个点和第四个点的x - offsetX

            //SolidUtil.EvaluateVertex(out DPoint3d staP, subEntities[1]);
            //SolidUtil.EvaluateVertex(out DPoint3d endP, subEntities[2]);
            //DSegment3d dSegment3D = new DSegment3d(staP, endP);
            //new LineElement(GeneralBank.Default3DModel, null, dSegment3D).AddToModel(); return;

            #endregion




            //foreach (var item in entity)
            //{
            //    if (item != null) item.AddToModel();
            //}

            return entity;
        }

        /// <summary>
        /// 计算线串与mesh的交点，uor尺度  斜线取交点
        /// </summary>
        /// <param name="lStrEl">线串元素</param>
        /// <param name="meshData">网格</param>
        /// <returns>交点</returns>
        public static DPoint3d[] CalculateIntersections(DPoint3d start, DPoint3d end, PolyfaceHeader meshData)
        {
            //PolyfaceVisitor polyfaceVisitor = PolyfaceVisitor.Attach(meshData, allData: true);
            //DRay3d ray = new DRay3d(start, end);
            //polyfaceVisitor.AdvanceToFacetBySearchRay(ray, tolerance: 0, out DPoint3d facetPoint, out double edgeFraction);
            //return facetPoint;

            //LineStringElement lStrEl = new LineStringElement(GeneralBank.Default3DModel, null, new DPoint3d[] { start, end });

            //if (lStrEl == null || meshData == null)
            //    return null;
            //List<DPoint3d> lStrPoints = GetLineStringElPoints(lStrEl);
            //算出路线上的点
            //线串投影到mesh，并计算交点
            CurveVector drapedCurve = meshData.DrapeLinestring(new DPoint3d[] { start, end }, DVector3d.UnitY);
            drapedCurve.GetStartEnd(out start, out end);
            return new DPoint3d[] { start, end };

            ////CurveVector drapedCurve = meshData.DrapeLinestring(lStrPoints, DVector3d.FromXYZ(0, 0, 1.0));
            //if (drapedCurve == null)
            //    return DPoint3d.Zero;
            //List<DPoint3d> dpli = CurveIntersection(lStrEl.GetCurveVector(), drapedCurve);
            //if (dpli.Count > 0)
            //{
            //    return dpli[0];
            //}
            //else
            //{
            //    return DPoint3d.Zero;
            //}
        }


        //精度控制，uor
        private static double s_tol = 0.1;
        private static List<DPoint3d> CurveIntersection(CurveVector curveA, CurveVector curveB)
        {
            List<DPoint3d> intersectPoints = new List<DPoint3d>();

            //计算线串与投影线的交点
            CurveVector intersectA = new CurveVector(CurveVector.BoundaryType.None);
            CurveVector intersectB = new CurveVector(CurveVector.BoundaryType.None);
            CurveCurve.IntersectionsXY(intersectA, intersectB, curveA, curveB);

            foreach (var prim in intersectA)
            {
                PartialCurveDetail detailA, detailB;
                CurveCurve.IsPartialCurveDetailPair(intersectA, intersectB, (uint)intersectA.IndexOf(prim), out detailA, out detailB);
                if (detailA.IsSingleFraction)
                {
                    DPoint3d pA, pB;
                    detailA.ParentCurve.FractionToPoint(detailA.Fraction0, out pA);
                    detailB.ParentCurve.FractionToPoint(detailB.Fraction0, out pB);
                    if (pA.Distance(pB) < s_tol)
                        intersectPoints.Add(pA);
                }
                else
                {
                    DPoint3d pA1, pA2, pB1, pB2;
                    detailA.ParentCurve.FractionToPoint(detailA.Fraction0, out pA1);
                    detailA.ParentCurve.FractionToPoint(detailA.Fraction1, out pA2);
                    detailB.ParentCurve.FractionToPoint(detailB.Fraction0, out pB1);
                    detailB.ParentCurve.FractionToPoint(detailB.Fraction1, out pB2);
                    double s = pA1.Distance(pB1);
                    if (pA1.Distance(pB1) < s_tol)
                        intersectPoints.Add(pA1);
                    s = pA2.Distance(pB2);

                    if (pA2.Distance(pB2) < s_tol)
                        intersectPoints.Add(pA2);
                }
            }

            return intersectPoints;
        }



        /// <summary>
        /// 获取线串元素上的点
        /// </summary>
        /// <param name="lStrEl"></param>
        /// <returns></returns>
        private static List<DPoint3d> GetLineStringElPoints(LineStringElement lStrEl)
        {
            List<DPoint3d> points = new List<DPoint3d>();

            CurveVector curve = lStrEl.GetCurveVector();
            curve.GetAt(0).TryGetLineString(points);
            return points;
        }



        //创建面
        public static PolyfaceHeader CreatePolyfaceHeader(List<DPoint3d> downDPoint3Ds, List<DPoint3d> topDPoint3Ds)
        {
            if (topDPoint3Ds.Count == 0)
            {
                List<DPoint3d> dPoint3DTops = new();
                dPoint3DTops.AddRange(downDPoint3Ds);

                List<DPoint3d> dPoint3DTopDowns = new();
                dPoint3DTopDowns.AddRange(topDPoint3Ds);

                dPoint3DTopDowns.Reverse();
                dPoint3DTops.AddRange(dPoint3DTopDowns);

                List<int> indices = new();
                PolyfaceHeader polyHeader = new()
                {
                    Point = dPoint3DTops
                };
                for (int i = 1; i <= dPoint3DTops.Count; i++)
                {
                    indices.Add(i);
                }
                polyHeader.AddIndexedFacet(indices, null, null, indices);
                MeshHeaderElement meshHeaderElement = new(GeneralBank.Default3DModel, null, polyHeader);
                return polyHeader;
            }
            else
            {
                LineStringElement lineStringElement = new(GeneralBank.Default3DModel, null, downDPoint3Ds.ToArray());
                List<DPoint3d> dPoint3DTops = new();
                dPoint3DTops.AddRange(topDPoint3Ds);
                dPoint3DTops.Reverse();
                LineStringElement lineStringElement2 = new(GeneralBank.Default3DModel, null, dPoint3DTops.ToArray());
                return CreatePolyfaceHeader(lineStringElement, lineStringElement2);
            }

        }

        //创建面
        public static PolyfaceHeader CreatePolyfaceHeader(LineStringElement curveCurveDown, LineStringElement curveCurveTop)
        {
            PolyfaceHeader polyfaceHeader = null;
            MeshSDKNET.CreateMeshFromTwoCurves(ref polyfaceHeader, curveCurveDown.GetCurveVector(), curveCurveTop.GetCurveVector(), GeneralBank.Default3DModel);
            return polyfaceHeader;
        }







        /// <summary>
        /// 
        /// </summary>
        /// <param name="shaftBottomCenterLength">跌水井水平长度</param>
        /// <param name="slop">坡度; (输入界面值, 例: 3%则输入3)</param>
        /// <returns></returns>
        public LineElement GetSlopLinee(double shaftBottomCenterLength, double slop)
        {
            double z = shaftBottomCenterLength * slop;
            DSegment3d dSegment3D = new DSegment3d(new DPoint3d(), new DPoint3d(shaftBottomCenterLength, 0, z) * Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster);
            return new LineElement(GeneralBank.Default3DModel, null, dSegment3D);
        }

        public LineElement GetSlopLinee(DPoint3d startPoint, double shaftBottomCenterLength, double slop)
        {
            shaftBottomCenterLength *= Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMaster;
            double x = shaftBottomCenterLength * slop;
            DPoint3d endPoint = new DPoint3d(startPoint.X + x, startPoint.Y, startPoint.Z + shaftBottomCenterLength);
            DSegment3d dSegment3D = new DSegment3d(startPoint, endPoint);
            return new LineElement(GeneralBank.Default3DModel, null, dSegment3D);
        }



    }
}